package com.alexvas.rtsp.codec.renderer;

import android.graphics.SurfaceTexture;
import android.opengl.EGL14;
import android.opengl.EGLContext;
import android.opengl.GLES20;
import android.util.Log;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

public class YUVRenderer implements Runnable {
    private static final String TAG = "YUVRenderer";

    private SurfaceTexture mSurfaceTexture;
    private int mWidth, mHeight;
    private boolean mIsRunning = false;
    private Thread mRenderThread;

    // OpenGL 资源
    private int mProgram;
    private int mTextureIdY, mTextureIdU, mTextureIdV;
    private int muSamplerYLoc, muSamplerULoc, muSamplerVLoc;
    private int maPositionLoc, maTextureCoordLoc;

    // 顶点坐标和纹理坐标
    private FloatBuffer mVertexBuffer;
    private FloatBuffer mTextureBuffer;

    // YUV 数据缓存
    private byte[] mYData, mUData, mVData;
    private int mYuvWidth, mYuvHeight;
    private final Object mYuvLock = new Object();

    // 顶点着色器
    private static final String VERTEX_SHADER =
        "attribute vec4 aPosition;" +
        "attribute vec2 aTextureCoord;" +
        "varying vec2 vTextureCoord;" +
        "void main() {" +
        "  gl_Position = aPosition;" +
        "  vTextureCoord = aTextureCoord;" +
        "}";

    // 片段着色器 (YUV to RGB 转换)
    private static final String FRAGMENT_SHADER =
        "precision mediump float;" +
        "varying vec2 vTextureCoord;" +
        "uniform sampler2D ySampler;" +
        "uniform sampler2D uSampler;" +
        "uniform sampler2D vSampler;" +
        "void main() {" +
        "  float y = texture2D(ySampler, vTextureCoord).r;" +
        "  float u = texture2D(uSampler, vTextureCoord).r;" +
        "  float v = texture2D(vSampler, vTextureCoord).r;" +
        "  // YUV to RGB conversion matrix (BT.601)" +
        "  float r = y + 1.402 * (v - 0.5);" +
        "  float g = y - 0.344 * (u - 0.5) - 0.714 * (v - 0.5);" +
        "  float b = y + 1.772 * (u - 0.5);" +
        "  gl_FragColor = vec4(r, g, b, 1.0);" +
        "}";

    public YUVRenderer(SurfaceTexture surfaceTexture, int width, int height) {
        mSurfaceTexture = surfaceTexture;
        mWidth = width;
        mHeight = height;

        // 初始化顶点和纹理坐标缓冲区（标准的全屏四边形）
        float[] vertices = {
            -1.0f, -1.0f,
             1.0f, -1.0f,
            -1.0f,  1.0f,
             1.0f,  1.0f
        };
        mVertexBuffer = ByteBuffer.allocateDirect(vertices.length * 4)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer()
                .put(vertices);
        mVertexBuffer.position(0);

        float[] textureCoords = {
            0.0f, 1.0f,
            1.0f, 1.0f,
            0.0f, 0.0f,
            1.0f, 0.0f
        };
        mTextureBuffer = ByteBuffer.allocateDirect(textureCoords.length * 4)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer()
                .put(textureCoords);
        mTextureBuffer.position(0);
    }

    public void startRender() {
        mIsRunning = true;
        mRenderThread = new Thread(this);
        mRenderThread.start();
    }

    public void stopRender() {
        mIsRunning = false;
        if (mRenderThread != null) {
            try {
                mRenderThread.join();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        releaseGLResources();
    }

    private void initGL() {
        try {
            EGLContext sharedContext = EGL14.EGL_NO_CONTEXT; // 通常使用默认上下文
            // 这里需要创建 EGL 环境，绑定到 SurfaceTexture
            // 为简洁，省略 EGL 初始化代码，可参考 Android 官方 Grafika 示例
            // 关键是创建 EGLSurface 并关联 mSurfaceTexture

            // 创建 OpenGL 程序
            mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
            if (mProgram == 0) {
                Log.e(TAG, "Failed to create program");
                return;
            }

            // 获取属性和 uniform 位置
            maPositionLoc = GLES20.glGetAttribLocation(mProgram, "aPosition");
            maTextureCoordLoc = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
            muSamplerYLoc = GLES20.glGetUniformLocation(mProgram, "ySampler");
            muSamplerULoc = GLES20.glGetUniformLocation(mProgram, "uSampler");
            muSamplerVLoc = GLES20.glGetUniformLocation(mProgram, "vSampler");

            // 生成 Y、U、V 三个纹理
            int[] textures = new int[3];
            GLES20.glGenTextures(3, textures, 0);
            mTextureIdY = textures[0];
            mTextureIdU = textures[1];
            mTextureIdV = textures[2];

            // 配置纹理参数
            for (int textureId : textures) {
                GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
                GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
                GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
                GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
                GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
            }
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);

        } catch (Exception e) {
            Log.e(TAG, "initGL error", e);
        }
    }

    private void renderFrame() {
        synchronized (mYuvLock) {
            if (mYData == null || mUData == null || mVData == null) return;
        }

        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

        GLES20.glUseProgram(mProgram);

        // 启用顶点数组
        GLES20.glEnableVertexAttribArray(maPositionLoc);
        GLES20.glVertexAttribPointer(maPositionLoc, 2, GLES20.GL_FLOAT, false, 0, mVertexBuffer);
        GLES20.glEnableVertexAttribArray(maTextureCoordLoc);
        GLES20.glVertexAttribPointer(maTextureCoordLoc, 2, GLES20.GL_FLOAT, false, 0, mTextureBuffer);

        // 上传 Y 分量
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIdY);
        GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, mYuvWidth, mYuvHeight, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(mYData));
        GLES20.glUniform1i(muSamplerYLoc, 0);

        // 上传 U 分量 (尺寸是 Y 的 1/4)
        GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIdU);
        GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, mYuvWidth / 2, mYuvHeight / 2, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(mUData));
        GLES20.glUniform1i(muSamplerULoc, 1);

        // 上传 V 分量
        GLES20.glActiveTexture(GLES20.GL_TEXTURE2);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIdV);
        GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, mYuvWidth / 2, mYuvHeight / 2, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(mVData));
        GLES20.glUniform1i(muSamplerVLoc, 2);

        // 绘制
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);

        // 解绑纹理
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
    }

    // 外部调用此方法更新 YUV 数据
    public void updateYUVData(byte[] y, byte[] u, byte[] v, int width, int height) {
        synchronized (mYuvLock) {
            mYData = y.clone();
            mUData = u.clone();
            mVData = v.clone();
            mYuvWidth = width;
            mYuvHeight = height;
        }
    }

    // 如果是 NV21 格式，需要拆分
    public void updateNV21Data(byte[] nv21, int width, int height) {
        int ySize = width * height;
        int uvSize = ySize / 4;

        byte[] y = new byte[ySize];
        byte[] u = new byte[uvSize];
        byte[] v = new byte[uvSize];

        System.arraycopy(nv21, 0, y, 0, ySize);
        for (int i = 0; i < uvSize; i++) {
            v[i] = nv21[ySize + i * 2];     // V 在偶数位
            u[i] = nv21[ySize + i * 2 + 1]; // U 在奇数位
        }
        updateYUVData(y, u, v, width, height);
    }

    private int createProgram(String vertexSource, String fragmentSource) {
        // 编译着色器和链接程序的辅助方法（略）
        // 可参考标准 OpenGL ES 创建流程
        return 0; // 实际实现中返回 program ID
    }

    private void releaseGLResources() {
        // 释放 OpenGL 资源（纹理、程序等）
    }

    @Override
    public void run() {
        // 初始化 EGL 和 OpenGL
        initGL();

        while (mIsRunning) {
            // 等待 VSync 或使用固定帧率
            // 渲染一帧
            renderFrame();
            // 交换缓冲区 (eglSwapBuffers)
        }
    }
}